package manager

import (
    "log"
    "time"
    "xncc_client/msg_list"
    "xncc_client/session"
)

type TcpClient struct {
    sess        *session.TcpSession
    serverAddr  string
    retryTmo    int
    msgChan     chan *msg_list.MsgWrapper
    msgHandlers map[uint32]msg_list.MsgHandler
}

func (m *TcpClient) Init(sAddr string) {
    m.serverAddr = sAddr
    m.retryTmo = 10
    m.msgChan = make(chan *msg_list.MsgWrapper, 1000)
}

func (m *TcpClient) RegisterHandler(protoId uint32, handler msg_list.MsgHandler) {
    m.msgHandlers[protoId] = handler
}

func (m *TcpClient) Start() {

    for {
        s := session.NewSession(m.serverAddr)
        if s == nil {
            log.Printf("connect failed and retry again in %d seconds\n", m.retryTmo)
        } else {
            m.sess = s
            break
        }
        time.Sleep(time.Second * time.Duration(m.retryTmo))
    }

    go func() {
        m.receive()
    }()

    go func() {
        m.handleMsg()
    }()
}

func (m *TcpClient) receive() {
    for {
        msgw, err := m.sess.ReceiveMsg()
        if err != nil {
            continue
        } else {
            m.msgChan <- msgw
        }
    }
}

func (m *TcpClient) handleMsg() {
    for {
        select {
        case msgw := <-m.msgChan:
            m.handleOneMsg(msgw)
        }
    }
}

func (m *TcpClient) handleOneMsg(mw *msg_list.MsgWrapper) {
    if _, ok := m.msgHandlers[mw.ProtoId]; !ok {
        log.Printf("msg id %d not register handler\n", mw.ProtoId)
    } else {
        m.msgHandlers[mw.ProtoId](mw.Msg)
    }
}

func (m *TcpClient) SendTestMsg(msg string) {
    m.sess.SendMsg(&msg_list.OnTestMsg{
        NumStr: msg,
    })
}
